package com.bauer.module.advice;

import com.bauer.module.common.error.ClockException;
import com.bauer.module.common.error.ErrorCode;
import com.bauer.module.common.error.RetryException;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @program: clock
 * @description:
 * @author: bauer weo
 * @create: 2019-09-03 20:28
 */
@Component
@Aspect
public class RetryAdvice {

    private int maxRetryTimes = 4;

    private static Logger logger = LoggerFactory.getLogger(RetryAdvice.class);

    @Pointcut("execution(public * com.bauer.module.service..*.*(..))")
    private void service() {

    }

    @Around("service()")
    public Object retryAround(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
        int retryTimes = 0;
        String name = proceedingJoinPoint.getSignature().getName();
        while (retryTimes < maxRetryTimes) {
            try {
                return proceedingJoinPoint.proceed();
            } catch (RetryException ex) {
                logger.error("retry service:{} ", name);
            } catch (ClockException cloex) {
                throw new ClockException(cloex.getErrorCode(), cloex.getErrorMsg());
            } catch (Throwable throwable) {
                logger.error("retryAround error ", throwable);
                throw new ClockException(ErrorCode.SYSTEM_ERROR);
            }
            retryTimes++;
        }
        throw new ClockException(ErrorCode.SYSTEM_ERROR);
    }
}
